/*!
 * \file wls_parse_message.c
 *
 * \brief weblogic message解析
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 *
 * \version 2.0
 * \author wuwk
 * \date 2015/11/20
 *
 */
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>

#include "frreport_comm.h"
#include "frbyte_buffer.h"
#include "wls_parse_message.h"

#define MQ_REPORT_MQ                     "mq"
#define MQ_REPORT_MQ_MSG                 "mq.message"
#define MQ_REPORT_MQ_MSGTYPE             "mq.message.type"

#define MQ_REPORT_MQ_MSG_TEXT            "mq.message.text"
#define MQ_REPORT_MQ_MSG_MAP             "mq.message.map"
#define MQ_REPORT_MQ_MSG_BIN             "mq.message.binary"

#define MQ_REPORT_MQ_TEXT                "text"
#define MQ_REPORT_MQ_MAP                 "hashmap"
#define MQ_REPORT_MQ_BIN                 "binary"

#define MQ_PRIORITY_REQ                  "request.mq.priority"
#define MQ_PRIORITY_RESP                 "response.mq.priority"
#define MQ_PRIORITY_PUB                  "publish.mq.priority"
#define MQ_PRIORITY_NOTIFY               "notify.mq.priority"

#define WLS_TYPE_STRING          102
#define WLS_TYPE_BOOLEAN         103
#define WLS_TYPE_INT             104
#define WLS_TYPE_LONG            105
#define WLS_TYPE_BYTE            106
#define WLS_TYPE_SHORT           107
#define WLS_TYPE_FLOAT           108
#define WLS_TYPE_DOUBLE          109
#define WLS_TYPE_CHAR            110
#define WLS_TYPE_BYTES           111
#define WLS_TYPE_BIGSTRING       112

union int32_float_bits {
    int32_t int_bits;
    float float_bits;
};

union int64_double_bits {
    int64_t int_bits;
    double double_bits;
};

/*!
 * 跳过UTF数据
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int wls_skip_utf(Frbyte_Packet *p_st_data)
{
    uint16_t u16_len = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_peek_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (u16_len != 0)
        bytebuff_skip(p_st_data, u16_len+2);

    return FR_SUCC;
}

/*!
 * 读Request
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop               (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int wls_request_read(Frbyte_Packet *p_st_data, int is_iiop)
{
    uint32_t u32_flag = 0;
    int j = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_int(p_st_data, 4, &u32_flag, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    j = u32_flag & 0xFF;
    if (j != 1)
        return FR_FAIL;

    if (u32_flag & 0x100)
    {
        // invocableId
        bytebuff_skip(p_st_data, 8);
    }

    if (u32_flag & 0x200)
        bytebuff_skip(p_st_data, 8); // long

    // MethodId
    bytebuff_skip(p_st_data, 4);

    return FR_SUCC;
}

/*!
 * 跳过属性
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int wls_skip_property(Frbyte_Packet *p_st_data)
{
    uint8_t u8_tmp = 0;
    uint32_t u32_len = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 1)
        return APM_L7_ANALYZE_TODO;

    if (bytebuff_peek_char(p_st_data, &u8_tmp) == FR_FAIL)
        return FR_FAIL;

    // 有属性
    if (u8_tmp == 0)
    {
        if (bytebuff_remaining(p_st_data) < 4)
            return APM_L7_ANALYZE_TODO;

        // 属性长度
        if (bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            return FR_FAIL;

        if (bytebuff_remaining(p_st_data) < (int)u32_len)
            return APM_L7_ANALYZE_TODO;
        bytebuff_skip(p_st_data, u32_len);
    }

    return FR_SUCC;
}

FR_STATIC int __wls_analysis_req_external(Frbyte_Packet *p_st_data)
{
    uint32_t u32_flag = 0;
    int j = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_int(p_st_data, 4, &u32_flag, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    j = u32_flag & 0xFF;
    if (j != 1)
        return FR_FAIL;

    if ((u32_flag & 0x100) != 0)
        bytebuff_skip(p_st_data, 16); // invocableId

    if ((u32_flag & 0x200) != 0)
        bytebuff_skip(p_st_data, 8);

    bytebuff_skip(p_st_data, 4); // methodId

    return FR_SUCC;
}

/*!
 * 解析消息开始前部分
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_body_data      (Frreport_body_data   上报链表)
 * \param *p_key               (char   上报key)
 * \param i_index              (int 消息的index)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int __wls_analysis_external(Frbyte_Packet *p_st_data
                          , Frreport_body_data *p_st_body_data
                          , char *p_key
                          , int i_index
                          , int is_iiop
                          , int i_stub_start)
{
    char arr_priority_key[64];
    uint8_t u8_priority = 0;
    uint8_t u8_has_msgid = 0;
    uint8_t u8_skip4 = 0;
    uint8_t u8_tmp = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL || p_key == NULL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 4)
        return APM_L7_ANALYZE_TODO;

    if (bytebuff_get_char(p_st_data, &u8_skip4) == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_get_char(p_st_data, &u8_has_msgid) == FR_FAIL)
        return FR_FAIL;

    bytebuff_skip(p_st_data, 1);
    // 消息优先级
    if (bytebuff_get_char(p_st_data, &u8_priority) == FR_FAIL)
        return FR_FAIL;

    if (strncmp(p_key, "request", 7) == 0)
        snprintf(arr_priority_key, sizeof(arr_priority_key), "%s", MQ_PRIORITY_REQ);
    else if (strncmp(p_key, "notify", 6) == 0)
        snprintf(arr_priority_key, sizeof(arr_priority_key), "%s.%d", MQ_PRIORITY_NOTIFY, i_index);
    else
        snprintf(arr_priority_key, sizeof(arr_priority_key), "%s.%d", MQ_PRIORITY_RESP, i_index);

    // 消息优先级上报
    i_ret = frreport_body_l7_add_int(p_st_body_data, arr_priority_key, u8_priority);
    if (i_ret == FR_FAIL)
        return FR_FAIL;

    if (u8_skip4 >= 30)
    {
        if (bytebuff_remaining(p_st_data) < 4)
            return APM_L7_ANALYZE_TODO;
        bytebuff_skip(p_st_data, 4);
    }

    // 有属性
    if ((u8_has_msgid & 0x1) != 0)
    {
        if (wls_skip_property(p_st_data) == FR_FAIL)
            return FR_FAIL;
    }

    // 有messageId
    if ((u8_has_msgid & 0x4) != 0)
    {
        if (bytebuff_get_char(p_st_data, &u8_tmp) == FR_FAIL)
            return FR_FAIL;

        //alignment
        if (is_iiop)
        {
            while(((bytebuff_getPosition(p_st_data) - i_stub_start) % 8) != 0)
                bytebuff_skip(p_st_data, 1);
        }

        if (u8_tmp == 12 || u8_tmp == 11)
        {
            if (bytebuff_remaining(p_st_data) < 16)
                return APM_L7_ANALYZE_TODO;
            bytebuff_skip(p_st_data, 16);
            if (u8_tmp & 0x40)
            {
                if (bytebuff_remaining(p_st_data) < 4)
                    return APM_L7_ANALYZE_TODO;
                bytebuff_skip(p_st_data, 4);
            }
        }
        else if (u8_tmp == 1)
        {
            if (bytebuff_remaining(p_st_data) < 20)
                return APM_L7_ANALYZE_TODO;
            bytebuff_skip(p_st_data, 20);
        }
        else
            return FR_FAIL;
    }

    if ((u8_has_msgid & 0x8) != 0)
    {
        if (bytebuff_remaining(p_st_data) < 4)
            return APM_L7_ANALYZE_TODO;
        bytebuff_skip(p_st_data, 4);
    }

    //alignment
    if (is_iiop)
    {
        while(((bytebuff_getPosition(p_st_data) - i_stub_start) % 4) != 0)
            bytebuff_skip(p_st_data, 1);
    }

    return FR_SUCC;
}

/*!
 * 跳过JMSID
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop              (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int __wls_skip_jms_id(Frbyte_Packet *p_st_data, int i_stub_start, int is_iiop)
{
    uint8_t u8_char = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_char(p_st_data, &u8_char) == FR_FAIL)
        return FR_FAIL;

    if (is_iiop)
    {
        //alignment
        while(((bytebuff_getPosition(p_st_data) - i_stub_start) % 8) != 0)
            bytebuff_skip(p_st_data, 1);
    }

    if (u8_char == 1)
        bytebuff_skip(p_st_data, 24);  //unique(long)+4+4+4+counter(int)
    else if (u8_char == 2)
        bytebuff_skip(p_st_data, 12); //unique(long)+counter(int)
    else
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 * 跳过dispatcherId
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop              (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int wls_skip_dispatcher_id(Frbyte_Packet *p_st_data, int is_iiop)
{
    uint8_t u8_char = 0;
    uint16_t u16_len = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_char(p_st_data, &u8_char) == FR_FAIL)
        return FR_FAIL;

    if (is_iiop)
        bytebuff_skip(p_st_data, 5);

    if (bytebuff_get_short(p_st_data, 2, &u16_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (is_iiop)
    {
        while ((u16_len % 4) != 0)
            u16_len++;
    }

    bytebuff_skip(p_st_data, u16_len); //name

    bytebuff_skip(p_st_data, 4); //hashCode

    return FR_SUCC;
}

/*!
 * 跳过backEndId
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop              (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int __wls_skip_backend_id(Frbyte_Packet *p_st_data, int i_stub_start, int is_iiop)
{
    uint8_t u8_char = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_char(p_st_data, &u8_char) == FR_FAIL)
        return FR_FAIL;

    if (u8_char != 1 && u8_char != 2)
        return FR_FAIL;

    // JMSID
    if (__wls_skip_jms_id(p_st_data, i_stub_start, is_iiop) == FR_FAIL)
        return FR_FAIL;

    if (u8_char == 2)
    {
        if (wls_skip_dispatcher_id(p_st_data, is_iiop) == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*!
 * 跳过destiantionId
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop              (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int __wls_skip_destination_id(Frbyte_Packet *p_st_data, int i_stub_start, int is_iiop)
{
    return __wls_skip_jms_id(p_st_data, i_stub_start, is_iiop);
}

/*!
 * 跳过backEndId和destiantionId
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param is_iiop              (int 是否是iiop)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int wls_backend_destination_id(Frbyte_Packet *p_st_data, int i_stub_start, int is_iiop)
{
    if (__wls_skip_backend_id(p_st_data, i_stub_start, is_iiop) == FR_FAIL)
        return FR_FAIL;

    if (__wls_skip_destination_id(p_st_data, i_stub_start, is_iiop) == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 * 读consumerReconnectInfo
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *
 */
int wls_read_consumer_reconnectinfo(Frbyte_Packet *p_st_data)
{
    uint32_t u32_flag = 0;
    int j = 0;

    if (p_st_data == NULL)
        return FR_FAIL;

    if (bytebuff_get_int(p_st_data, 4, &u32_flag, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    j = u32_flag & 0xFF;
    if (j != 1)
        return FR_FAIL;

    //delayServerClose
    if (u32_flag & 0x2000)
    {
        if (bytebuff_skip(p_st_data, 8) == FR_FAIL)
            return FR_FAIL;
    }

    //lastAckMsgId(JMSMessageId)
    if (u32_flag & 0x8000)
    {
        if (bytebuff_skip(p_st_data, 8) == FR_FAIL)
            return FR_FAIL;
    }

    //lastExposeMsgId(JMSMessageId)
    if (u32_flag & 0x1000)
    {
        if (bytebuff_skip(p_st_data, 8) == FR_FAIL)
            return FR_FAIL;
    }

    //clientId(JMSID)
    if (u32_flag & 0x100)
    {
        if (__wls_skip_jms_id(p_st_data, 0, 0) == FR_FAIL)
            return FR_FAIL;
    }

    //serverId(JMSID)
    if (u32_flag & 0x200)
    {
        if (__wls_skip_jms_id(p_st_data, 0, 0) == FR_FAIL)
            return FR_FAIL;
    }

    //clientDispatcherId
    if (u32_flag & 0x400)
    {
        if (wls_skip_dispatcher_id(p_st_data, 0) == FR_FAIL)
            return FR_FAIL;
    }

    //serverDispatcherId
    if (u32_flag & 0x800)
    {
        if (wls_skip_dispatcher_id(p_st_data, 0) == FR_FAIL)
            return FR_FAIL;
    }

    //invocableId(JMSID)
    if (u32_flag & 0x4000)
    {
        if (__wls_skip_jms_id(p_st_data, 0, 0) == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}

/*!
 * textmessage解析
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_body_data      (Frreport_body_data   上报链表)
 * \param *p_key               (char   上报key)
 * \param i_index              (int 消息的index)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int wls_analysis_textmessage(Frbyte_Packet *p_st_data
                           , Frreport_body_data *p_st_body_data
                           , char *p_key
                           , int i_index
                           , int is_iiop
                           , int i_stub_start)
{
    char arr_key[64];
    char arr_msgtype[64];
    char *p_data = NULL;
    uint8_t u8_utf8 = 0;
    uint8_t u8_tmp = 0;
    uint8_t u8_boolean = 0;
    uint32_t u32_data_len = 0;
    unsigned int ui_left_len = 0;
    unsigned int ui_report_len = 0;
    int i_obj = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL || p_key == NULL)
        return FR_FAIL;

    if (__wls_analysis_external(p_st_data, p_st_body_data, p_key, i_index, is_iiop, i_stub_start) == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 1)
        return APM_L7_ANALYZE_TODO;

    if (bytebuff_get_char(p_st_data, &u8_tmp) == FR_FAIL)
        return FR_FAIL;

    if (strncmp(p_key, "request", 7) == 0)
    {
        snprintf(arr_key, sizeof(arr_key), "%s.%s", p_key, MQ_REPORT_MQ_MSG_TEXT);
        // message.type
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s", p_key, MQ_REPORT_MQ_MSGTYPE);
    }
    else
    {
        snprintf(arr_key, sizeof(arr_key), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSG_TEXT, i_index);
        // message.type
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSGTYPE, i_index);
    }

    switch (u8_tmp & 0x7F)
    {
        case 1:
        case 2:
            if (bytebuff_remaining(p_st_data) < 1)
                return APM_L7_ANALYZE_TODO;

            if (bytebuff_get_char(p_st_data, &u8_boolean) == FR_FAIL)
                return FR_FAIL;
            if (u8_boolean == 0)
            {
                if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_TEXT) == FR_FAIL)
                    return FR_FAIL;
                if (frreport_body_l7_add_str(p_st_body_data, arr_key, "") == FR_FAIL)
                    return FR_FAIL;
                return FR_SUCC;
            }
            i_obj = 1;
            break;
        case 3:
            if (bytebuff_remaining(p_st_data) < 1)
                return APM_L7_ANALYZE_TODO;

            if (bytebuff_get_char(p_st_data, &u8_boolean) == FR_FAIL)
                return FR_FAIL;
            if (u8_boolean == 0)
            {
                if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_TEXT) == FR_FAIL)
                    return FR_FAIL;
                if (frreport_body_l7_add_str(p_st_body_data, arr_key, "") == FR_FAIL)
                    return FR_FAIL;
                return FR_SUCC;
            }

            if (bytebuff_remaining(p_st_data) < 1)
                return APM_L7_ANALYZE_TODO;

            if (bytebuff_get_char(p_st_data, &u8_utf8) == FR_FAIL)
                return FR_FAIL;
            if ((u8_utf8 & 0x2) == 0)
                i_obj = 1;

            if (is_iiop)
                bytebuff_skip(p_st_data, 1);
            break;
        default:
            return FR_SUCC;
    }

    if (bytebuff_remaining(p_st_data) < 4)
        return APM_L7_ANALYZE_TODO;
    /* 消息长度 */
    if (bytebuff_get_int(p_st_data, 4, &u32_data_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (u32_data_len == 0)
    {
        if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_TEXT) == FR_FAIL)
            return FR_FAIL;

        if (frreport_body_l7_add_str(p_st_body_data, arr_key, "") == FR_FAIL)
            return FR_FAIL;

        return FR_SUCC;
    }

    ui_left_len = bytebuff_remaining(p_st_data);
    if (ui_left_len < u32_data_len && ui_left_len < APM_REPORT_MQ_MAX)
        return APM_L7_ANALYZE_TODO;

    ui_report_len = ui_left_len < u32_data_len ? ui_left_len : u32_data_len;

    p_data = (char *)frmalloc(ui_report_len + 1);
    if (p_data == NULL)
        return FR_FAIL;

    i_ret = bytebuff_get_bytes(p_st_data, p_data, ui_report_len);
    if (i_ret == FR_FAIL)
    {
        frfree(p_data);
        return FR_FAIL;
    }

    p_data[ui_report_len] = '\0';

    // utf-8
    if (i_obj == 0)
    {
        // message.type上报
        if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_TEXT) == FR_FAIL)
            return FR_FAIL;

        if (FRREPORT_BODY_L7_ADD_STR_LIMIT(p_st_body_data, arr_key, p_data) == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }
    else
    {
        // message.type上报
        if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_BIN) == FR_FAIL)
            return FR_FAIL;

        if (strncmp(p_key, "request", 7) == 0)
            snprintf(arr_key, sizeof(arr_key), "%s.%s", p_key, MQ_REPORT_MQ_MSG_BIN);
        else
            snprintf(arr_key, sizeof(arr_key), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSG_BIN, i_index);
        if (frreport_body_l7_add_bin(p_st_body_data, arr_key, p_data, ui_report_len) == FR_FAIL)
        {
            frfree(p_data);
            return FR_FAIL;
        }
    }

    frfree(p_data);

    return FR_SUCC;
}

/*!
 * mapmessage解析
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_body_data      (Frreport_body_data   上报链表)
 * \param *p_key               (char   上报key)
 * \param i_index              (int 消息的index)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int wls_analysis_mapmessage(Frbyte_Packet *p_st_data
                          , Frreport_body_data *p_st_body_data
                          , char *p_key
                          , int i_index
                          , int is_iiop
                          , int i_stub_start)
{
    char arr_key[64];
    char arr_msgtype[64];
    char arr_tmp[8];
    char *p_map_key = NULL;
    char *p_map_value = NULL;
    uint8_t u8_value = 0;
    uint8_t u8_flag = 0;
    uint16_t u16_value = 0;
    uint16_t u16_num = 0;
    uint16_t u16_key_len = 0;
    uint16_t u16_type = 0;
    uint16_t u16_value_len = 0;
    uint32_t u32_value = 0;
    uint32_t u32_len = 0;
    uint32_t u32_data_len = 0;
    uint64_t u64_value = 0;
    unsigned int ui_left_len = 0;
    union int32_float_bits u_32bits;
    union int64_double_bits u_64bits;
    float f_value = 0.0;
    double db_value = 0.0;
    int i = 0;

    if (p_st_data == NULL || p_st_body_data == NULL || p_key == NULL)
        return FR_FAIL;

    if (__wls_analysis_external(p_st_data, p_st_body_data, p_key, i_index, is_iiop, i_stub_start) == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 5)
        return APM_L7_ANALYZE_TODO;

    if (bytebuff_get_char(p_st_data, &u8_flag) == FR_FAIL)
        return FR_FAIL;

    if (u8_flag < 1 || u8_flag > 2)
         return FR_FAIL;

    if (is_iiop)
        bytebuff_skip(p_st_data, 3);

    if (bytebuff_get_int(p_st_data, 4, &u32_data_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    ui_left_len = bytebuff_remaining(p_st_data);
    if (ui_left_len < u32_data_len && ui_left_len < APM_REPORT_MQ_MAX)
        return APM_L7_ANALYZE_TODO;

    // message.type
    if (strncmp(p_key, "request", 7) == 0)
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s", p_key, MQ_REPORT_MQ_MSGTYPE);
    else
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSGTYPE, i_index);
    if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_MAP) == FR_FAIL)
        return FR_FAIL;

    // ac ed 00 05 xx xx xx xx
    bytebuff_skip(p_st_data, 8);
    if (bytebuff_get_short(p_st_data, 2, &u16_num, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    for (; i < u16_num; i++)
    {
        bytebuff_skip(p_st_data, 2);
        // key长度
        if (bytebuff_get_short(p_st_data, 2, &u16_key_len, BYTE_BIG_ENDIAN) == FR_FAIL)
            goto err;

        p_map_key = (char *)frmalloc(u16_key_len + 1);
        if (p_map_key == NULL)
            goto err;
        memset(p_map_key, 0x00, u16_key_len + 1);

        // key
        if (bytebuff_get_bytes(p_st_data, p_map_key, u16_key_len) == FR_FAIL)
            goto err;

        if (strncmp(p_key, "request", 7) == 0)
            snprintf(arr_key, sizeof(arr_key), "%s.%s.%s", p_key, MQ_REPORT_MQ_MSG_MAP, p_map_key);
        else
            snprintf(arr_key, sizeof(arr_key), "%s.%s.%d.%s", p_key, MQ_REPORT_MQ_MSG_MAP, i_index, p_map_key);
        frfree(p_map_key);
        p_map_key = NULL;

        // 数据类型
        if (bytebuff_get_short(p_st_data, 2, &u16_type, BYTE_BIG_ENDIAN) == FR_FAIL)
            goto err;

        switch (u16_type)
        {
            case WLS_TYPE_STRING:
                // string长度
                if (bytebuff_get_short(p_st_data, 2, &u16_value_len, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                p_map_value = (char *)frmalloc(u16_value_len + 1);
                if (p_map_value == NULL)
                    goto err;
                memset(p_map_value, 0x00, u16_value_len + 1);

                if (bytebuff_get_bytes(p_st_data, p_map_value, u16_value_len) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_str(p_st_body_data, arr_key, p_map_value) == FR_FAIL)
                    goto err;

                frfree(p_map_value);
                p_map_value = NULL;
                break;
            case WLS_TYPE_BOOLEAN:
                if (bytebuff_get_char(p_st_data, &u8_value) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_int(p_st_body_data, arr_key, u8_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_INT:
                if (bytebuff_get_int(p_st_data, 4, &u32_value, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_int(p_st_body_data, arr_key, u32_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_LONG:
                if (bytebuff_get_long(p_st_data, 8, &u64_value, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_int(p_st_body_data, arr_key, u64_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_BYTE:
                if (bytebuff_get_char(p_st_data, &u8_value) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_int(p_st_body_data, arr_key, u8_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_SHORT:
                if (bytebuff_get_short(p_st_data, 2, &u16_value, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_int(p_st_body_data, arr_key, u16_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_FLOAT:
                if (bytebuff_get_int(p_st_data, 4, &u32_value, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                u_32bits.int_bits = u32_value;
                f_value = u_32bits.float_bits;

                if (frreport_body_l7_add_float(p_st_body_data, arr_key, f_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_DOUBLE:
                if (bytebuff_get_long(p_st_data, 8, &u64_value, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                u_64bits.int_bits = u64_value;
                db_value = u_64bits.double_bits;

                if (frreport_body_l7_add_double(p_st_body_data, arr_key, db_value) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_CHAR:
                bytebuff_skip(p_st_data, 1);
                if (bytebuff_get_char(p_st_data, &u8_value) == FR_FAIL)
                    goto err;

                snprintf(arr_tmp, sizeof(arr_tmp), "%c", u8_value);
                if (frreport_body_l7_add_str(p_st_body_data, arr_key, arr_tmp) == FR_FAIL)
                    goto err;
                break;
            case WLS_TYPE_BYTES:
                // 长度
                if (bytebuff_get_int(p_st_data, 4, &u32_len, BYTE_BIG_ENDIAN) == FR_FAIL)
                    goto err;

                p_map_value = (char *)frmalloc(u32_len + 1);
                if (p_map_value == NULL)
                    goto err;
                memset(p_map_value, 0x00, u32_len + 1);

                if (bytebuff_get_bytes(p_st_data, p_map_value, u32_len) == FR_FAIL)
                    goto err;

                if (frreport_body_l7_add_bin(p_st_body_data, arr_key, p_map_value, u32_len) == FR_FAIL)
                    goto err;

                frfree(p_map_value);
                p_map_value = NULL;
                break;
            default:
                break;
        }
    }

    return FR_SUCC;

err:
    if (p_map_key)
        frfree(p_map_key);
    if (p_map_value)
        frfree(p_map_value);

    return FR_FAIL;
}

/*!
 * objectmessage,streammessage解析
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_body_data      (Frreport_body_data   上报链表)
 * \param *p_key               (char   上报key)
 * \param i_index              (int 消息的index)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int wls_analysis_objmessage(Frbyte_Packet *p_st_data
                          , Frreport_body_data *p_st_body_data
                          , char *p_key
                          , int i_index
                          , int is_iiop
                          , int i_stub_start)
{
    char arr_key[64];
    char arr_msgtype[64];
    uint32_t u32_data_len = 0;
    uint8_t u8_flag = 0;
    unsigned int ui_left_len = 0;
    unsigned int ui_report_len = 0;

    if (p_st_data == NULL || p_st_body_data == NULL || p_key == NULL)
        return FR_FAIL;

    if (__wls_analysis_external(p_st_data, p_st_body_data, p_key, i_index, is_iiop, i_stub_start) == FR_FAIL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 5)
        return APM_L7_ANALYZE_TODO;

    if (bytebuff_get_char(p_st_data, &u8_flag) == FR_FAIL)
        return FR_FAIL;

    if (u8_flag < 1 || u8_flag > 3)
         return FR_FAIL;

    if (is_iiop)
        bytebuff_skip(p_st_data, 3);

    if (bytebuff_get_int(p_st_data, 4, &u32_data_len, BYTE_BIG_ENDIAN) == FR_FAIL)
        return FR_FAIL;

    if (strncmp(p_key, "request", 7) == 0)
    {
        // message.type
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s", p_key, MQ_REPORT_MQ_MSGTYPE);
        snprintf(arr_key, sizeof(arr_key), "%s.%s", p_key, MQ_REPORT_MQ_MSG_BIN);
    }
    else
    {
        // message.type
        snprintf(arr_msgtype, sizeof(arr_msgtype), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSGTYPE, i_index);
        snprintf(arr_key, sizeof(arr_key), "%s.%s.%d", p_key, MQ_REPORT_MQ_MSG_BIN, i_index);
    }

    // message.type上报
    if (frreport_body_l7_add_str(p_st_body_data, arr_msgtype, MQ_REPORT_MQ_BIN) == FR_FAIL)
        return FR_FAIL;

    if (u32_data_len == 0)
    {
        if (frreport_body_l7_add_bin(p_st_body_data, arr_key, "", 0) == FR_FAIL)
            return FR_FAIL;
        return FR_SUCC;
    }

    ui_left_len = bytebuff_remaining(p_st_data);
    if (ui_left_len < u32_data_len && ui_left_len < APM_REPORT_MQ_MAX)
        return APM_L7_ANALYZE_TODO;

    ui_report_len = ui_left_len < u32_data_len ? ui_left_len : u32_data_len;

    bytebuff_skip(p_st_data, ui_report_len);
    // 上报
    if (frreport_body_l7_add_bin(p_st_body_data, arr_key, NULL, ui_report_len) == FR_FAIL)
        return FR_FAIL;

    return FR_SUCC;
}

/*!
 * 消息解析
 *
 * \param *p_st_data           (Frbyte_Packet          数据)
 * \param *p_st_body_data      (Frreport_body_data   上报链表)
 * \param *p_key               (char 上报key)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据包不完整
 *
 */
int wls_message_analysis(Frbyte_Packet *p_st_data
                       , Frreport_body_data *p_st_body_data
                       , char *p_key
                       , int is_iiop
                       , int i_stub_start)
{
    char arr_size[64];
    uint8_t u8_msg_type = 0;
    uint8_t u8_index = 1;
    uint32_t u32_flag = 0;
    int i_ret = 0;

    if (p_st_data == NULL || p_st_body_data == NULL || p_key == NULL)
        return FR_FAIL;

    if (bytebuff_remaining(p_st_data) < 12)
        return APM_L7_ANALYZE_TODO;

    while (1)
    {
        bytebuff_skip(p_st_data, 2);
        // 消息类型
        if (bytebuff_get_char(p_st_data, &u8_msg_type) == FR_FAIL)
            return FR_FAIL;

//        bytebuff_skip(p_st_data, 9);
        bytebuff_skip(p_st_data, 1);

        __wls_analysis_req_external(p_st_data);

        switch (u8_msg_type)
        {
            case WLS_MAPMESSAGE:
                i_ret = wls_analysis_mapmessage(p_st_data, p_st_body_data, p_key, u8_index, is_iiop, i_stub_start);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case WLS_OBJMESSAGE:
            case WLS_STREAMMESSAGE:
            case WLS_BYTEMESSAGE:
                i_ret = wls_analysis_objmessage(p_st_data, p_st_body_data, p_key, u8_index, is_iiop, i_stub_start);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            case WLS_MESSAGE:
            case WLS_TEXTMESSAGE:
                i_ret = wls_analysis_textmessage(p_st_data, p_st_body_data, p_key, u8_index, is_iiop, i_stub_start);
                if (i_ret == FR_FAIL)
                    return FR_FAIL;
                break;
            default:
                return FR_FAIL;
        }

        if (i_ret == APM_L7_ANALYZE_TODO)
            return APM_L7_ANALYZE_TODO;

        if (is_iiop)
        {
            while(((bytebuff_getPosition(p_st_data) - i_stub_start) % 4) != 0)
                bytebuff_skip(p_st_data, 1);

            if (bytebuff_remaining(p_st_data) < 8)
            {
                bytebuff_skip(p_st_data, bytebuff_remaining(p_st_data));
                break;
            }

            bytebuff_skip(p_st_data, 8);
            if (bytebuff_get_int(p_st_data, 4, &u32_flag, BYTE_BIG_ENDIAN) == FR_FAIL)
                return FR_FAIL;

            if (u32_flag == 0)
                bytebuff_skip(p_st_data, 4);
            bytebuff_skip(p_st_data, 20); //8+12

            if (bytebuff_remaining(p_st_data) == 4)
            {
                bytebuff_skip(p_st_data, 4);
                break;
            }
        }
        else
        {
            if (bytebuff_remaining(p_st_data) <= 29)
                break;

            bytebuff_skip(p_st_data, 25);
        }
        u8_index++;
    }

    if (bytebuff_remaining(p_st_data))
        bytebuff_skip(p_st_data, bytebuff_remaining(p_st_data));

    if (strncmp(p_key, "request", 7) != 0)
    {
        snprintf(arr_size, sizeof(arr_size), "%s.%s", p_key, MQ_REPORT_MESSAGE_SIZE);
        // 消息个数上报
        i_ret = frreport_body_l7_add_int(p_st_body_data, arr_size, u8_index);
        if (i_ret == FR_FAIL)
            return FR_FAIL;
    }

    return FR_SUCC;
}
